'''
Created on 09/06/2010

@author: eh01
'''
from datastore.resource import Resource
from datastore.spaces import Spaces
from datastore.uri import Uri
from edais.soap_service import SOAPService
from xml.dom import minidom
from xml.etree import ElementTree
import logging
import os
import unittest
from edais import soap_service


        
class SOAPServiceTest(unittest.TestCase):
    
    CONFIGURATION_FILE_PATH = '../../src/mapping/configuration.xml'
    CONFIGURATION_FILE_PATH_WHEN_RUNNING_FROM_ANT = '../src/mapping/configuration.xml'
    MAPPING_ARTEFACTS_DIRECTORY = '../../src/mapping/artefacts'
    MAPPING_ARTEFACTS_DIRECTORY_WHEN_RUNNING_FROM_ANT = '../src/mapping/artefacts'
    SPEAR_APP_FILE_PATH = '%s.xml'
    SPEAR_APP_FILE_PATH_WHEN_RUNNING_FROM_ANT = '../test/edaistest/%s.xml'
    EDAIS_MSG_FILE_PATH = '%s'
    EDAIS_MSG_FILE_PATH_WHEN_RUNNING_FROM_ANT = '../test/edaistest/%s'
    
    def setUp(self):
        pass
    
    def tearDown(self):
        pass

    def load_mapping_files(self, spaces):
        mapping_config_rs = Resource(type="temp")
        if os.path.isfile(SOAPServiceTest.CONFIGURATION_FILE_PATH):
            configuration_file_path = SOAPServiceTest.CONFIGURATION_FILE_PATH
            mapping_artefacts_directory = SOAPServiceTest.MAPPING_ARTEFACTS_DIRECTORY
        else:
            configuration_file_path = SOAPServiceTest.CONFIGURATION_FILE_PATH_WHEN_RUNNING_FROM_ANT
            mapping_artefacts_directory = SOAPServiceTest.MAPPING_ARTEFACTS_DIRECTORY_WHEN_RUNNING_FROM_ANT
        mapping_config_rs.load_from_file(configuration_file_path)
        i = 0
        for cur_dir, dirs, files in os.walk(mapping_artefacts_directory):
            for file in files:
                if file.endswith('.xml'):
                    file_path = os.path.join(cur_dir, file)
                    mapping_rs = Resource(type="temp")
                    mapping_rs.load_from_file(file_path)
                    mapping_rs_uri = mapping_config_rs.definitions['term:eplanning/mapping/row'].autoload_prefix + \
                            mapping_rs.get_metadata(Uri("term:base/build/autoload_suffix"))
                    i += 1
                    spaces.put(mapping_rs_uri, mapping_rs)
    
    def load_serialised_spear_app(self, spaces, spear_ref):
        if os.path.isfile(SOAPServiceTest.SPEAR_APP_FILE_PATH % spear_ref):
            spear_app_file_path = SOAPServiceTest.SPEAR_APP_FILE_PATH
        else:
            spear_app_file_path = SOAPServiceTest.SPEAR_APP_FILE_PATH_WHEN_RUNNING_FROM_ANT
        app = Resource(type="spear:app")
        app.load_from_file(spear_app_file_path % spear_ref)
        spaces.put(Uri('spear:app/%s' % spear_ref), app)      
    
    def open_expected_response(self, file_name):
        if os.path.isfile(SOAPServiceTest.EDAIS_MSG_FILE_PATH % file_name):
            edais_msg_file_path = SOAPServiceTest.EDAIS_MSG_FILE_PATH
        else:
            edais_msg_file_path = SOAPServiceTest.EDAIS_MSG_FILE_PATH_WHEN_RUNNING_FROM_ANT
        return open(edais_msg_file_path % file_name).read()
    
    def test_find_element(self):
        a = ElementTree.Element('{http://a}A')
        b = ElementTree.SubElement(a, '{http://b}B')
        b1 = ElementTree.SubElement(b, '{http://b}B1')        
        c = ElementTree.SubElement(b, '{http://c}C')
        d = ElementTree.SubElement(c, '{http://d}D')
        soap_srv = SOAPService(spaces=Spaces(), uri=Uri())
        element = soap_srv.find_element('./{http://b}B/{http://c}C/{http://d}D', a)
        self.assertEqual(d, element)
        try:
            soap_srv.find_element('./{http://b}B/{http://b}B2', a)
        except Exception, e:
            self.assertEqual("Expected element '{http://b}B2' in element '{http://a}A/{http://b}B'", str(e))
        else:
            self.fail('Should have raised an exception')
    
    def test_create_end_of_queue_application(self):
        spear_ref = 'S000001E'
        msg_namespace = 'http://a/'
        expected_application_element = ElementTree.Element('{%s}Application' % msg_namespace)
        expected_application_number_element = ElementTree.SubElement(expected_application_element, '{%s}ApplicationNumber' % 'http://xml.gov.au/edais/core/da.data.2.3.0r2')
        expected_application_number_element.text = spear_ref
        soap_srv = SOAPService(spaces=Spaces(), uri=Uri())
        application_element = soap_srv.create_end_of_queue_application(msg_namespace, spear_ref)
        self.assertEqual(get_elements_as_string(expected_application_element), get_elements_as_string(application_element))
        
    
    def test_get_sender_data(self):
        soap_srv = SOAPService(spaces=Spaces(), uri=Uri())
        sender_authority = "CPS"
        sender_id = "CPSID"
        sender_process_role = "Initiator"
        request_message_namespace = 'http://xml.gov.au/edais/bm/DeclareSaveStatusChangeApplicationNotification.msg.2.3.0r2'
        request_message_name = 'DeclareSaveStatusChangeApplicationNotification'
        envelope_element = ElementTree.Element('{http://schemas.xmlsoap.org/soap/envelope/}Envelope')
        body_element = ElementTree.SubElement(envelope_element, '{http://schemas.xmlsoap.org/soap/envelope/}Body')
        msg_element = ElementTree.SubElement(body_element, '{%s}%s' % (request_message_namespace, request_message_name))
        sbmh_element = ElementTree.SubElement(msg_element, '{%s}StandardBusinessMessageHeader' % request_message_namespace)
        sender_party_element = ElementTree.SubElement(sbmh_element, '{http://xml.gov.au/edais/core/msg.data.2.3.0r2}SenderPartner')
        authority_element = ElementTree.SubElement(sender_party_element, '{http://xml.gov.au/edais/core/msg.data.2.3.0r2}Authority')
        authority_element.text = sender_authority
        # try to get sender data when all elements aren't present and check for error
        try:
            expected_exception_msg = "Expected element '{http://xml.gov.au/edais/core/msg.data.2.3.0r2}DocumentIdentification' in element '{http://schemas.xmlsoap.org/soap/envelope/}Envelope/{http://schemas.xmlsoap.org/soap/envelope/}Body/{http://xml.gov.au/edais/bm/DeclareSaveStatusChangeApplicationNotification.msg.2.3.0r2}DeclareSaveStatusChangeApplicationNotification/{http://xml.gov.au/edais/bm/DeclareSaveStatusChangeApplicationNotification.msg.2.3.0r2}StandardBusinessMessageHeader'\nExpected element '{http://xml.gov.au/edais/core/msg.data.2.3.0r2}ID' in element '{http://schemas.xmlsoap.org/soap/envelope/}Envelope/{http://schemas.xmlsoap.org/soap/envelope/}Body/{http://xml.gov.au/edais/bm/DeclareSaveStatusChangeApplicationNotification.msg.2.3.0r2}DeclareSaveStatusChangeApplicationNotification/{http://xml.gov.au/edais/bm/DeclareSaveStatusChangeApplicationNotification.msg.2.3.0r2}StandardBusinessMessageHeader/{http://xml.gov.au/edais/core/msg.data.2.3.0r2}SenderPartner'\nExpected element '{http://xml.gov.au/edais/core/msg.data.2.3.0r2}ProcessRole' in element '{http://schemas.xmlsoap.org/soap/envelope/}Envelope/{http://schemas.xmlsoap.org/soap/envelope/}Body/{http://xml.gov.au/edais/bm/DeclareSaveStatusChangeApplicationNotification.msg.2.3.0r2}DeclareSaveStatusChangeApplicationNotification/{http://xml.gov.au/edais/bm/DeclareSaveStatusChangeApplicationNotification.msg.2.3.0r2}StandardBusinessMessageHeader/{http://xml.gov.au/edais/core/msg.data.2.3.0r2}SenderPartner'"
            soap_srv.get_sender_data(request_message_namespace, request_message_name, envelope_element)
        except Exception, e:
            self.assertEqual(expected_exception_msg, str(e))
        else:
            self.fail('Should have raised an exception')
            
        # add the missing elements in sender data and check the method retrieves the data correctly
        document_id_element = ElementTree.SubElement(sbmh_element, '{%s}DocumentIdentification' % soap_service.msg_data_tns)
        instance_id_element = ElementTree.SubElement(document_id_element, '{%s}InstanceID' % soap_service.msg_data_tns)
        instance_id_element.text = '550e8400-e29b-41d4-a716-446655440000'
        id_element = ElementTree.SubElement(sender_party_element, '{http://xml.gov.au/edais/core/msg.data.2.3.0r2}ID')
        id_element.text = sender_id
        process_role_element = ElementTree.SubElement(sender_party_element, '{http://xml.gov.au/edais/core/msg.data.2.3.0r2}ProcessRole')
        process_role_element.text = sender_process_role
        sender_data = soap_srv.get_sender_data(request_message_namespace, request_message_name, envelope_element)
        self.assertEqual(sender_authority, sender_data['Authority'])
        self.assertEqual(sender_id, sender_data['ID'])
        self.assertEqual(sender_process_role, sender_data['ProcessRole'])
        
    def test_get_handle_declare_status_change_application_data(self):
        logger = logging.getLogger('soap_service_unittest_logger')
        soap_srv = SOAPService(spaces=Spaces(), uri=Uri())
        sender_authority = "CPS"
        sender_id = "CPSID"
        sender_process_role = "Initiator"
        instance_id = '550e8400-e29b-41d4-a716-446655440000'
        sender_data = {}
        sender_data[soap_service.SENDER_DOC_ID_INSTANCE_ID] = instance_id
        sender_data['Authority'] = sender_authority
        sender_data['ID'] = sender_id
        sender_data['ProcessRole'] = sender_process_role
        application_number = 'S000001E'
        council_reference_number_1 = '123'
        council_reference_number_2 = '456'
        request_message_namespace = 'http://xml.gov.au/edais/bm/DeclareSaveStatusChangeApplicationNotification.msg.2.3.0r2'
        request_message_name = 'DeclareSaveStatusChangeApplicationNotification'
        envelope_element = ElementTree.Element('{http://schemas.xmlsoap.org/soap/envelope/}Envelope')
        body_element = ElementTree.SubElement(envelope_element, '{http://schemas.xmlsoap.org/soap/envelope/}Body')
        msg_element = ElementTree.SubElement(body_element, '{%s}%s' % (request_message_namespace, request_message_name))
        application_element = ElementTree.SubElement(msg_element, '{%s}Application' % request_message_namespace)
        sbmh_element = ElementTree.SubElement(msg_element, '{%s}StandardBusinessMessageHeader' % request_message_namespace)
        
        data = soap_srv.get_handle_declare_status_change_application_data(envelope_element, logger)
        expected_exception_msg = """Expected element '{http://xml.gov.au/edais/core/da.data.2.3.0r2}ApplicationNumber' in element '{http://schemas.xmlsoap.org/soap/envelope/}Envelope/{http://schemas.xmlsoap.org/soap/envelope/}Body/{http://xml.gov.au/edais/bm/DeclareSaveStatusChangeApplicationNotification.msg.2.3.0r2}DeclareSaveStatusChangeApplicationNotification/{http://xml.gov.au/edais/bm/DeclareSaveStatusChangeApplicationNotification.msg.2.3.0r2}Application'
Expected element '{http://xml.gov.au/edais/core/msg.data.2.3.0r2}DocumentIdentification' in element '{http://schemas.xmlsoap.org/soap/envelope/}Envelope/{http://schemas.xmlsoap.org/soap/envelope/}Body/{http://xml.gov.au/edais/bm/DeclareSaveStatusChangeApplicationNotification.msg.2.3.0r2}DeclareSaveStatusChangeApplicationNotification/{http://xml.gov.au/edais/bm/DeclareSaveStatusChangeApplicationNotification.msg.2.3.0r2}StandardBusinessMessageHeader'
Expected element '{http://xml.gov.au/edais/core/msg.data.2.3.0r2}SenderPartner' in element '{http://schemas.xmlsoap.org/soap/envelope/}Envelope/{http://schemas.xmlsoap.org/soap/envelope/}Body/{http://xml.gov.au/edais/bm/DeclareSaveStatusChangeApplicationNotification.msg.2.3.0r2}DeclareSaveStatusChangeApplicationNotification/{http://xml.gov.au/edais/bm/DeclareSaveStatusChangeApplicationNotification.msg.2.3.0r2}StandardBusinessMessageHeader'
Expected element '{http://xml.gov.au/edais/core/msg.data.2.3.0r2}SenderPartner' in element '{http://schemas.xmlsoap.org/soap/envelope/}Envelope/{http://schemas.xmlsoap.org/soap/envelope/}Body/{http://xml.gov.au/edais/bm/DeclareSaveStatusChangeApplicationNotification.msg.2.3.0r2}DeclareSaveStatusChangeApplicationNotification/{http://xml.gov.au/edais/bm/DeclareSaveStatusChangeApplicationNotification.msg.2.3.0r2}StandardBusinessMessageHeader'
Expected element '{http://xml.gov.au/edais/core/msg.data.2.3.0r2}SenderPartner' in element '{http://schemas.xmlsoap.org/soap/envelope/}Envelope/{http://schemas.xmlsoap.org/soap/envelope/}Body/{http://xml.gov.au/edais/bm/DeclareSaveStatusChangeApplicationNotification.msg.2.3.0r2}DeclareSaveStatusChangeApplicationNotification/{http://xml.gov.au/edais/bm/DeclareSaveStatusChangeApplicationNotification.msg.2.3.0r2}StandardBusinessMessageHeader'
Expected element '{http://xml.gov.au/edais/bm/DeclareSaveStatusChangeApplicationNotification.msg.2.3.0r2}Specialisation' in element '{http://schemas.xmlsoap.org/soap/envelope/}Envelope/{http://schemas.xmlsoap.org/soap/envelope/}Body/{http://xml.gov.au/edais/bm/DeclareSaveStatusChangeApplicationNotification.msg.2.3.0r2}DeclareSaveStatusChangeApplicationNotification'
Expected element '{http://xml.gov.au/edais/bm/DeclareSaveStatusChangeApplicationNotification.msg.2.3.0r2}Specialisation' in element '{http://schemas.xmlsoap.org/soap/envelope/}Envelope/{http://schemas.xmlsoap.org/soap/envelope/}Body/{http://xml.gov.au/edais/bm/DeclareSaveStatusChangeApplicationNotification.msg.2.3.0r2}DeclareSaveStatusChangeApplicationNotification'"""
        self.assertEqual(expected_exception_msg, "\n".join([str(e) for e in data[4]]))
            
        application_number_element = ElementTree.SubElement(application_element, '{%s}ApplicationNumber' % 'http://xml.gov.au/edais/core/da.data.2.3.0r2')
        application_number_element.text = application_number
        specialisation_element = ElementTree.SubElement(msg_element, '{%s}Specialisation' % request_message_namespace)
        extension_element = ElementTree.SubElement(specialisation_element, '{%s}Extension' % 'http://xml.gov.au/edais/core/specialisation.data.2.3.0r2')
        council_reference_numbers_element = ElementTree.SubElement(extension_element, '{%s}CouncilReferenceNumbers' % 'http://www.edais.gov.au/nat/extension.data.2.3.0r2.v.0.5')
        responsible_authority_reference_number_1_element = ElementTree.SubElement(council_reference_numbers_element, '{%s}ResponsibleAuthorityReferenceNumber1' % 'http://www.edais.gov.au/nat/extension.data.2.3.0r2.v.0.5')
        responsible_authority_reference_number_1_element.text = council_reference_number_1
        responsible_authority_reference_number_2_element = ElementTree.SubElement(council_reference_numbers_element, '{%s}ResponsibleAuthorityReferenceNumber2' % 'http://www.edais.gov.au/nat/extension.data.2.3.0r2.v.0.5')
        responsible_authority_reference_number_2_element.text = council_reference_number_2
        sender_party_element = ElementTree.SubElement(sbmh_element, '{http://xml.gov.au/edais/core/msg.data.2.3.0r2}SenderPartner')
        authority_element = ElementTree.SubElement(sender_party_element, '{http://xml.gov.au/edais/core/msg.data.2.3.0r2}Authority')
        authority_element.text = sender_authority
        document_id_element = ElementTree.SubElement(sbmh_element, '{%s}DocumentIdentification' % soap_service.msg_data_tns)
        instance_id_element = ElementTree.SubElement(document_id_element, '{%s}InstanceID' % soap_service.msg_data_tns)
        instance_id_element.text =  instance_id       
        id_element = ElementTree.SubElement(sender_party_element, '{http://xml.gov.au/edais/core/msg.data.2.3.0r2}ID')
        id_element.text = sender_id
        process_role_element = ElementTree.SubElement(sender_party_element, '{http://xml.gov.au/edais/core/msg.data.2.3.0r2}ProcessRole')
        process_role_element.text = sender_process_role
        
        data = soap_srv.get_handle_declare_status_change_application_data(envelope_element, logger)
        self.assertEqual(application_number, data[0])
        self.assertEqual(sender_data, data[1])
        self.assertEqual(council_reference_number_1, data[2])
        self.assertEqual(council_reference_number_2, data[3])
    
    def test_construct_reply_public_status_application_response_edais_soap_message(self):
        soap_srv = SOAPService(spaces=Spaces(), uri=Uri())
        expected_env = ElementTree.Element('{http://schemas.xmlsoap.org/soap/envelope/}Envelope')
        body = ElementTree.SubElement(expected_env, '{http://schemas.xmlsoap.org/soap/envelope/}Body')
        msg = ElementTree.SubElement(body, '{%s}ReplyPublicStatusApplicationResponse' % 'http://xml.gov.au/edais/bm/ReplyPublicStatusApplicationResponse.msg.2.3.0r2')        
        application_element = ElementTree.SubElement(msg, 'Application')
        specialisation_element = ElementTree.SubElement(msg, 'Specialisation')
        sbmh_element = ElementTree.SubElement(msg, 'StandardBusinessMessageHeader')
        env = soap_srv.construct_reply_public_status_application_response_edais_soap_message(application_element, specialisation_element, sbmh_element)
        self.assertEqual(get_elements_as_string(expected_env), get_elements_as_string(env))
        
        # test without specialisation element
        expected_env = ElementTree.Element('{http://schemas.xmlsoap.org/soap/envelope/}Envelope')
        body = ElementTree.SubElement(expected_env, '{http://schemas.xmlsoap.org/soap/envelope/}Body')
        msg = ElementTree.SubElement(body, '{%s}ReplyPublicStatusApplicationResponse' % 'http://xml.gov.au/edais/bm/ReplyPublicStatusApplicationResponse.msg.2.3.0r2')        
        application_element = ElementTree.SubElement(msg, 'Application')
        specialisation_element = None
        sbmh_element = ElementTree.SubElement(msg, 'StandardBusinessMessageHeader')
        env = soap_srv.construct_reply_public_status_application_response_edais_soap_message(application_element, specialisation_element, sbmh_element)
        self.assertEqual(get_elements_as_string(expected_env), get_elements_as_string(env))
    
    def test_handle_query_public_status_application(self):
        soap_message_request = """<ns0:Envelope xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope/">
   <ns0:Header>
      <ns1:To xmlns:ns1="http://www.w3.org/2005/08/addressing">http://localhost:8080</ns1:To>
      <ns1:Action xmlns:ns1="http://www.w3.org/2005/08/addressing">http://example.xml.gov.au/QueryPublicStatusApplication_Responder.2.3.0r2/Query_Response</ns1:Action>
   </ns0:Header>
   <ns0:Body>
      <ns1:QueryRequestPublicStatusApplicationQuery xmlns:ns1="http://xml.gov.au/edais/bm/QueryRequestPublicStatusApplicationQuery.msg.2.3.0r2">
         <ns1:Application>
            <ns2:ApplicationNumber xmlns:ns2="http://xml.gov.au/edais/core/da.data.2.3.0r2">S007789J</ns2:ApplicationNumber>
         </ns1:Application>
         <ns1:StandardBusinessMessageHeader>
            <ns2:BusinessScope xmlns:ns2="http://xml.gov.au/edais/core/msg.data.2.3.0r2">
               <ns2:Type>BusinessCollaborations</ns2:Type>
            </ns2:BusinessScope>
            <ns2:DocumentIdentification xmlns:ns2="http://xml.gov.au/edais/core/msg.data.2.3.0r2">
               <ns2:CreationDateTime>2002-05-30T09:30:10Z</ns2:CreationDateTime>
               <ns2:InstanceID>S007789J</ns2:InstanceID>
               <ns2:Standard>eDAIS</ns2:Standard>
               <ns2:Type>QueryRequestPublicApplicationStatusQuery</ns2:Type>
               <ns2:TypeVersion>2.3.0r2</ns2:TypeVersion>
            </ns2:DocumentIdentification>
            <ns2:ReceiverPartner xmlns:ns2="http://xml.gov.au/edais/core/msg.data.2.3.0r2">
               <ns2:Authority>SPEAR</ns2:Authority>
               <ns2:ID>SPEAR</ns2:ID>
               <ns2:ProcessRole>Responder</ns2:ProcessRole>
            </ns2:ReceiverPartner>
            <ns2:SenderPartner xmlns:ns2="http://xml.gov.au/edais/core/msg.data.2.3.0r2">
               <ns2:Authority>CPS</ns2:Authority>
               <ns2:ID>CPS</ns2:ID>
               <ns2:ProcessRole>Initiator</ns2:ProcessRole>
            </ns2:SenderPartner>
            <ns2:Version xmlns:ns2="http://xml.gov.au/edais/core/msg.data.2.3.0r2">0-5</ns2:Version>
         </ns1:StandardBusinessMessageHeader>
      </ns1:QueryRequestPublicStatusApplicationQuery>
   </ns0:Body>
</ns0:Envelope>"""
        spaces = Spaces()
        self.load_mapping_files(spaces)
        logger = logging.getLogger('soap_service_unittest_logger')
        spear_ref = 'S007789J'
        self.load_serialised_spear_app(spaces, spear_ref)
        mapping_index_rs = spaces.get(Uri("internal:eplanning/mapping/index"))
        soap_srv = SOAPService(spaces=spaces, uri=Uri())
        response_message = soap_srv.handle_query_public_status_application(soap_message_request, spaces, mapping_index_rs, 'http://localhost:6101/edais/artefacts/biv/bm/queryPublicStatusApplication/QueryRequestPublicStatusApplicationQuery.msg.2.3.0r2.xsd', logger)
        expected_response_message = self.open_expected_response('ReplyPublicStatusApplicationResponse_S007789J.xml')
        envelope_element = ElementTree.XML(response_message)
        expected_envelope_element = ElementTree.XML(expected_response_message)
        self.align_creation_date_times_in_response_message_and_response_message(expected_envelope_element, envelope_element, soap_service.REPLY_PUBLIC_STATUS_APPLICATION_RESPONSE_MSG_NS, soap_service.REPLY_PUBLIC_STATUS_APPLICATION_RESPONSE_MSG_NAME)
        self.assertEqual(raw_xml(get_elements_as_string(expected_envelope_element)), 
                 raw_xml(get_elements_as_string(envelope_element)))    

    def test_handle_query_public_status_application_connectivitytest(self):
        soap_message_request = """<ns0:Envelope xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope/">
   <ns0:Body>
      <ns1:QueryRequestPublicStatusApplicationQuery xmlns:ns1="http://xml.gov.au/edais/bm/QueryRequestPublicStatusApplicationQuery.msg.2.3.0r2">
         <ns1:Application>
            <ns2:ApplicationNumber xmlns:ns2="http://xml.gov.au/edais/core/da.data.2.3.0r2">connectivitytes</ns2:ApplicationNumber>
         </ns1:Application>
         <ns1:StandardBusinessMessageHeader>
            <ns2:BusinessScope xmlns:ns2="http://xml.gov.au/edais/core/msg.data.2.3.0r2">
               <ns2:Type>BusinessCollaboration</ns2:Type>
            </ns2:BusinessScope>
            <ns2:DocumentIdentification xmlns:ns2="http://xml.gov.au/edais/core/msg.data.2.3.0r2">
               <ns2:CreationDateTime>2010-06-29T15:31:18</ns2:CreationDateTime>
               <ns2:InstanceID>asdf</ns2:InstanceID>
               <ns2:Standard>eDAIS</ns2:Standard>
               <ns2:Type>QueryRequestPublicApplicationStatusQuery</ns2:Type>
               <ns2:TypeVersion>2.3.0r2</ns2:TypeVersion>
            </ns2:DocumentIdentification>
            <ns2:ReceiverPartner xmlns:ns2="http://xml.gov.au/edais/core/msg.data.2.3.0r2">
               <ns2:Authority>SPEAR</ns2:Authority>
               <ns2:ID>SPEAR</ns2:ID>
               <ns2:ProcessRole>Responder</ns2:ProcessRole>
            </ns2:ReceiverPartner>
            <ns2:SenderPartner xmlns:ns2="http://xml.gov.au/edais/core/msg.data.2.3.0r2">
               <ns2:Authority>CPS</ns2:Authority>
               <ns2:ID>CPS</ns2:ID>
               <ns2:ProcessRole>Initiator</ns2:ProcessRole>
            </ns2:SenderPartner>
            <ns2:Version xmlns:ns2="http://xml.gov.au/edais/core/msg.data.2.3.0r2">0-5</ns2:Version>
         </ns1:StandardBusinessMessageHeader>
      </ns1:QueryRequestPublicStatusApplicationQuery>
   </ns0:Body>
</ns0:Envelope>"""
        spaces = Spaces()
        self.load_mapping_files(spaces)
        logger = logging.getLogger('soap_service_unittest_logger')      
        mapping_index_rs = spaces.get(Uri("internal:eplanning/mapping/index"))
        soap_srv = SOAPService(spaces=spaces, uri=Uri())
        response_message = soap_srv.handle_query_public_status_application(soap_message_request, spaces, mapping_index_rs, 'http://localhost:6101/edais/artefacts/biv/bm/queryPublicStatusApplication/QueryRequestPublicStatusApplicationQuery.msg.2.3.0r2.xsd', logger)
        expected_response_message = self.open_expected_response('ReplyPublicStatusApplicationResponse_connectivitytest.xml')     
        envelope_element = ElementTree.XML(response_message)
        expected_envelope_element = ElementTree.XML(expected_response_message)
        self.align_creation_date_times_in_response_message_and_response_message(expected_envelope_element, envelope_element, soap_service.REPLY_PUBLIC_STATUS_APPLICATION_RESPONSE_MSG_NS, soap_service.REPLY_PUBLIC_STATUS_APPLICATION_RESPONSE_MSG_NAME)
        self.assertEqual(raw_xml(get_elements_as_string(expected_envelope_element)), 
                 raw_xml(get_elements_as_string(envelope_element)))    
        
    def test_handle_declare_status_change_application(self):
        soap_message_request = """<ns0:Envelope xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope/">
   <ns0:Header>
      <ns1:To xmlns:ns1="http://www.w3.org/2005/08/addressing">http://localhost:8080</ns1:To>
      <ns1:Action xmlns:ns1="http://www.w3.org/2005/08/addressing">http://example.xml.gov.au/DeclareStatusChangeApplication_Responder.2.3.0r2/Declare</ns1:Action>
   </ns0:Header>
   <ns0:Body>
      <ns1:DeclareSaveStatusChangeApplicationNotification xmlns:ns1="http://xml.gov.au/edais/bm/DeclareSaveStatusChangeApplicationNotification.msg.2.3.0r2">
         <ns1:Application>
            <ns2:ApplicationNumber xmlns:ns2="http://xml.gov.au/edais/core/da.data.2.3.0r2">S007533P</ns2:ApplicationNumber>
         </ns1:Application>
         <ns1:Specialisation>
            <ns2:DomainId xmlns:ns2="http://xml.gov.au/edais/core/specialisation.data.2.3.0r2">SPEAR</ns2:DomainId>
            <ns2:Extension xmlns:ns2="http://xml.gov.au/edais/core/specialisation.data.2.3.0r2">
               <ns3:CouncilReferenceNumbers xmlns:ns3="http://www.edais.gov.au/nat/extension.data.2.3.0r2.v.0.5">
                  <ns3:ResponsibleAuthorityReferenceNumber1>123</ns3:ResponsibleAuthorityReferenceNumber1>
                  <ns3:ResponsibleAuthorityReferenceNumber2>456</ns3:ResponsibleAuthorityReferenceNumber2>
               </ns3:CouncilReferenceNumbers>
            </ns2:Extension>
            <ns2:Jurisdiction xmlns:ns2="http://xml.gov.au/edais/core/specialisation.data.2.3.0r2">VIC</ns2:Jurisdiction>
            <ns2:Version xmlns:ns2="http://xml.gov.au/edais/core/specialisation.data.2.3.0r2">2-3-0r2</ns2:Version>
         </ns1:Specialisation>
         <ns1:StandardBusinessMessageHeader>
            <ns2:BusinessScope xmlns:ns2="http://xml.gov.au/edais/core/msg.data.2.3.0r2">
               <ns2:Type>BusinessCollaboration</ns2:Type>
            </ns2:BusinessScope>
            <ns2:DocumentIdentification xmlns:ns2="http://xml.gov.au/edais/core/msg.data.2.3.0r2">
               <ns2:CreationDateTime>2002-05-30T09:30:10Z</ns2:CreationDateTime>
               <ns2:InstanceID>S007533P</ns2:InstanceID>
               <ns2:Standard>eDAIS</ns2:Standard>
               <ns2:Type>DeclareSaveStatusChangeApplication</ns2:Type>
               <ns2:TypeVersion>2.3.0r2</ns2:TypeVersion>
            </ns2:DocumentIdentification>
            <ns2:ReceiverPartner xmlns:ns2="http://xml.gov.au/edais/core/msg.data.2.3.0r2">
               <ns2:Authority>SPEAR</ns2:Authority>
               <ns2:ID>SPEAR</ns2:ID>
               <ns2:ProcessRole>Responder</ns2:ProcessRole>
            </ns2:ReceiverPartner>
            <ns2:SenderPartner xmlns:ns2="http://xml.gov.au/edais/core/msg.data.2.3.0r2">
               <ns2:Authority>CPS</ns2:Authority>
               <ns2:ID>CPSID</ns2:ID>
               <ns2:ProcessRole>Initiator</ns2:ProcessRole>
            </ns2:SenderPartner>
            <ns2:Version xmlns:ns2="http://xml.gov.au/edais/core/msg.data.2.3.0r2">0-5</ns2:Version>
         </ns1:StandardBusinessMessageHeader>
      </ns1:DeclareSaveStatusChangeApplicationNotification>
   </ns0:Body>
</ns0:Envelope>"""
        spaces = Spaces()
        self.load_mapping_files(spaces)
        logger = logging.getLogger('soap_service_unittest_logger') 
        spear_ref = 'S007533P'
        self.load_serialised_spear_app(spaces, spear_ref)          
        mapping_index_rs = spaces.get(Uri("internal:eplanning/mapping/index"))
        soap_srv = SOAPService(spaces=spaces, uri=Uri())
        response_message = soap_srv.handle_declare_status_change_application(soap_message_request, spaces, mapping_index_rs, logger)
        expected_response_message = self.open_expected_response('ReceiptAcknowledgementSignal_S007533P.xml')    
        envelope_element = ElementTree.XML(response_message)
        expected_envelope_element = ElementTree.XML(expected_response_message)
        self.align_creation_date_times_in_response_message_and_response_message(expected_envelope_element, envelope_element, soap_service.RECEIPT_ACKNOWLEDGEMENT_SIGNAL_MSG_NS, soap_service.RECEIPT_ACKNOWLEDGEMENT_SIGNAL_MSG_NAME)        
        self.align_timestamp_in_response_message_and_response_message(expected_envelope_element, envelope_element, soap_service.RECEIPT_ACKNOWLEDGEMENT_SIGNAL_MSG_NS, soap_service.RECEIPT_ACKNOWLEDGEMENT_SIGNAL_MSG_NAME)
        self.assertEqual(raw_xml(get_elements_as_string(expected_envelope_element)), 
                 raw_xml(get_elements_as_string(envelope_element)))                    
        
    def test_handle_declare_status_change_application_no_council_ref(self):
        soap_message_request = """<ns0:Envelope xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope/">
   <ns0:Header>
      <ns1:To xmlns:ns1="http://www.w3.org/2005/08/addressing">http://localhost:8080</ns1:To>
      <ns1:Action xmlns:ns1="http://www.w3.org/2005/08/addressing">http://example.xml.gov.au/DeclareStatusChangeApplication_Responder.2.3.0r2/Declare</ns1:Action>
   </ns0:Header>
   <ns0:Body>
      <ns1:DeclareSaveStatusChangeApplicationNotification xmlns:ns1="http://xml.gov.au/edais/bm/DeclareSaveStatusChangeApplicationNotification.msg.2.3.0r2">
         <ns1:Application>
            <ns2:ApplicationNumber xmlns:ns2="http://xml.gov.au/edais/core/da.data.2.3.0r2">S007533P</ns2:ApplicationNumber>
         </ns1:Application>
         <ns1:Specialisation>
            <ns2:DomainId xmlns:ns2="http://xml.gov.au/edais/core/specialisation.data.2.3.0r2">SPEAR</ns2:DomainId>
            <ns2:Extension xmlns:ns2="http://xml.gov.au/edais/core/specialisation.data.2.3.0r2">
            </ns2:Extension>
            <ns2:Jurisdiction xmlns:ns2="http://xml.gov.au/edais/core/specialisation.data.2.3.0r2">VIC</ns2:Jurisdiction>
            <ns2:Version xmlns:ns2="http://xml.gov.au/edais/core/specialisation.data.2.3.0r2">2-3-0r2</ns2:Version>
         </ns1:Specialisation>
         <ns1:StandardBusinessMessageHeader>
            <ns2:BusinessScope xmlns:ns2="http://xml.gov.au/edais/core/msg.data.2.3.0r2">
               <ns2:Type>BusinessCollaboration</ns2:Type>
            </ns2:BusinessScope>
            <ns2:DocumentIdentification xmlns:ns2="http://xml.gov.au/edais/core/msg.data.2.3.0r2">
               <ns2:CreationDateTime>2002-05-30T09:30:10Z</ns2:CreationDateTime>
               <ns2:InstanceID>S007533P</ns2:InstanceID>
               <ns2:Standard>eDAIS</ns2:Standard>
               <ns2:Type>DeclareSaveStatusChangeApplication</ns2:Type>
               <ns2:TypeVersion>2.3.0r2</ns2:TypeVersion>
            </ns2:DocumentIdentification>
            <ns2:ReceiverPartner xmlns:ns2="http://xml.gov.au/edais/core/msg.data.2.3.0r2">
               <ns2:Authority>SPEAR</ns2:Authority>
               <ns2:ID>SPEAR</ns2:ID>
               <ns2:ProcessRole>Responder</ns2:ProcessRole>
            </ns2:ReceiverPartner>
            <ns2:SenderPartner xmlns:ns2="http://xml.gov.au/edais/core/msg.data.2.3.0r2">
               <ns2:Authority>CPS</ns2:Authority>
               <ns2:ID>CPSID</ns2:ID>
               <ns2:ProcessRole>Initiator</ns2:ProcessRole>
            </ns2:SenderPartner>
            <ns2:Version xmlns:ns2="http://xml.gov.au/edais/core/msg.data.2.3.0r2">0-5</ns2:Version>
         </ns1:StandardBusinessMessageHeader>
      </ns1:DeclareSaveStatusChangeApplicationNotification>
   </ns0:Body>
</ns0:Envelope>"""
        spaces = Spaces()
        self.load_mapping_files(spaces)
        logger = logging.getLogger('soap_service_unittest_logger') 
        spear_ref = 'S007533P'
        self.load_serialised_spear_app(spaces, spear_ref)
        mapping_index_rs = spaces.get(Uri("internal:eplanning/mapping/index"))
        soap_srv = SOAPService(spaces=spaces, uri=Uri())
        response_message = soap_srv.handle_declare_status_change_application(soap_message_request, spaces, mapping_index_rs, logger)
        expected_response_message = self.open_expected_response('ReceiptExceptionSignal_S007533P.xml')
        envelope_element = ElementTree.XML(response_message)
        expected_envelope_element = ElementTree.XML(expected_response_message)
        self.align_fault_creation_date_times_in_response_message_and_response_message(expected_envelope_element, envelope_element, soap_service.RECEIPT_EXCEPTION_SIGNAL_MSG_NS, soap_service.RECEIPT_EXCEPTION_SIGNAL_MSG_NAME)        
        self.assertEqual(raw_xml(get_elements_as_string(expected_envelope_element)), 
                 raw_xml(get_elements_as_string(envelope_element)))       
   
    def align_creation_date_times_in_response_message_and_response_message(self, expected_envelope_element, envelope_element, message_ns, message_name):
        creation_date_time_element = envelope_element.find('./{%s}Body/{%s}%s/{%s}StandardBusinessMessageHeader/{%s}DocumentIdentification/{%s}CreationDateTime'
                                       % (soap_service.SOAP_ENV_NS, 
                                          message_ns,
                                          message_name, 
                                          message_ns,
                                          soap_service.msg_data_tns,
                                          soap_service.msg_data_tns))
        expected_creation_date_time_element = expected_envelope_element.find('./{%s}Body/{%s}%s/{%s}StandardBusinessMessageHeader/{%s}DocumentIdentification/{%s}CreationDateTime'
                                       % (soap_service.SOAP_ENV_NS, 
                                          message_ns,
                                          message_name, 
                                          message_ns,
                                          soap_service.msg_data_tns,
                                          soap_service.msg_data_tns))
        expected_creation_date_time_element.text = creation_date_time_element.text

    def align_timestamp_in_response_message_and_response_message(self, expected_envelope_element, envelope_element, message_ns, message_name):
        timestamp_element = envelope_element.find('./{%s}Body/{%s}%s/{%s}ReceiptAcknowledgement/{%s}Timestamp'
                                       % (soap_service.SOAP_ENV_NS, 
                                          message_ns,
                                          message_name, 
                                          message_ns,
                                          soap_service.msg_data_tns))
        expected_timestamp_element = expected_envelope_element.find('./{%s}Body/{%s}%s/{%s}ReceiptAcknowledgement/{%s}Timestamp'
                                       % (soap_service.SOAP_ENV_NS, 
                                          message_ns,
                                          message_name, 
                                          message_ns,
                                          soap_service.msg_data_tns))
        expected_timestamp_element.text = timestamp_element.text
        
    def align_fault_creation_date_times_in_response_message_and_response_message(self, expected_envelope_element, envelope_element, message_ns, message_name):
        creation_date_time_element = envelope_element.find('./{%s}Body/{%s}Fault/detail/{%s}%s/{%s}StandardBusinessMessageHeader/{%s}DocumentIdentification/{%s}CreationDateTime'
                                       % (soap_service.SOAP_ENV_NS,
                                          soap_service.SOAP_ENV_NS,
                                          message_ns,
                                          message_name, 
                                          message_ns,
                                          soap_service.msg_data_tns,
                                          soap_service.msg_data_tns))
        expected_creation_date_time_element = expected_envelope_element.find('./{%s}Body/{%s}Fault/detail/{%s}%s/{%s}StandardBusinessMessageHeader/{%s}DocumentIdentification/{%s}CreationDateTime'
                                       % (soap_service.SOAP_ENV_NS,
                                          soap_service.SOAP_ENV_NS, 
                                          message_ns,
                                          message_name, 
                                          message_ns,
                                          soap_service.msg_data_tns,
                                          soap_service.msg_data_tns))
        expected_creation_date_time_element.text = creation_date_time_element.text
        
class EDAISPayloadTest(unittest.TestCase):


    def setUp(self):
#        self.ds = DataStore(":memory:")
#        mapping_config = Resource(type="temp")
#        mapping_config.load_from_file("../mapping/configuration.xml")        
#        self.ds.put([mapping_config])
#        self.row_autoload_prefix = mapping_config.definitions['term:eplanning/mapping/row'].autoload_prefix
#        index_autoload_prefix = mapping_config.definitions['term:eplanning/mapping/index'].autoload_prefix
#        upload_script.load_mapping_resource_into_datastore('../../SPEAR to SPEAR Adaptor to eDAIS Mapping v11.csv', self.ds)
#        self.spaces = Spaces()
#        self.mapping_resources = self.ds.find([(Uri("term:base/datastore/resource/type"), Uri("term:eplanning/mapping/row"))])
#        for rs in self.mapping_resources:
#            uri = self.row_autoload_prefix + rs.get_metadata(Uri("term:base/build/autoload_suffix"))
#            self.spaces.put(uri, rs)
#        self.mapping_index = self.ds.find([(Uri("term:base/datastore/resource/type"), Uri("term:eplanning/mapping/index"))])[0]
#        uri = index_autoload_prefix + rs.get_metadata(Uri("term:base/build/autoload_suffix"))
#        self.spaces.put(uri, self.mapping_index)
#        self.eDAISPayload = EDAISPayload()
        pass        
        
    def tearDown(self):
        # for some reason between each test python is retaining the reference to some
        # instances in the previous test. Hence to force garbage collection we will set the
        # variable to None here
        spaces = None
        mapping_resources = None
              
        
def get_elements_as_string(root_element):
    class dummy:
        pass    
    data = []
    file = dummy()
    file.write = data.append
    ElementTree.ElementTree(root_element).write(file, None)
    return "".join(data)

def raw_xml(xml_str):
    xml = minidom.parseString(xml_str)
    return u''.join([unicode(line).strip() for line in xml.toprettyxml().splitlines()])
        
if __name__ == "__main__":
    #import sys;sys.argv = ['', 'Test.testName']
    unittest.main()